import { Provide, Inject } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
import * as ExcelJS from "exceljs";
import { UploadStreamFileInfo } from '@midwayjs/busboy';

interface OptionsType {
  headerFields: string[]; // 表头字段
  tableData: any[]; // 解析的表格数据
  entityName: any; // 实体类名
  updateSupport: boolean; // 是否更新已经存在的用户数据 true/false
  uniqueKey: string; // 唯一字段的key名，不能重复，只有通过该参数，才能判断是否有重复值
  createBy?,
  additionalCondition?: any, // 新增：支持额外的查询条件（如 class.id）
}

@Provide()
export class ResolveExcelService {
  @Inject()
  ctx: Context;

  // 解析前端上传的excel文件，变成可读数据流，默认模板只有一张表
  async resolvedWebExcelStream(files: UploadStreamFileInfo) {
    const { ctx } = this
    const fileStream: any = files[0]
    const mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
    const readStream = fileStream.data;
    if (fileStream.mimeType === mimeType) {
      try { }
      catch (err) {
        console.log('err', err)
      }
      const workbook = new ExcelJS.Workbook();
      // 获取第一个表格的数据
      // const worksheets = await workbook.xlsx.read(fileStream.data)
      const worksheets = await workbook.xlsx.read(readStream)
      const worksheet = worksheets.getWorksheet(1)

      let sheetValue = worksheet.getSheetValues()
      // 去除空数组
      sheetValue = sheetValue.filter((item: any) => item.length > 0)
      // 去除二维数组里一维数组的第一项
      const handleResultArray = []
      sheetValue.forEach((item: any) => {
        item.shift()
        handleResultArray.push(item)
      })
      let tableHeader = handleResultArray[0] // 表头
      let tableData = handleResultArray.filter((item, index) => index > 0) // 表格数据
      // 清除当前上传的文件，这里只需要解析，不需要上传到临时文件夹中，所以在此删除，后期需从根本优化
      await ctx.cleanupRequestFiles()
      return {
        tableHeader,
        tableData,
        originTable: handleResultArray,
      }
    } else {
      ctx.throw(500, '不是excel文件')
    }
  }

  // 分析导入：提示与写入数据库
  async analysisExcelAndWhite(options: OptionsType) {
    // 解构参数并设置默认值
    const {
      tableData,
      entityName,
      updateSupport = false,
      uniqueKey,
      createBy = null,
      additionalCondition = {}, // 新增：支持额外的查询条件（如 class.id）
    } = options;

    const failList: Array<{ line: number; name: string }> = [];
    const successList: Array<{ line: number; name: string }> = [];

    console.debug('开始处理数据，共 %d 条', tableData.length);
    console.debug('操作人:', createBy || '系统自动');

    try {
      for (const [index, currentItem] of tableData.entries()) {
        const lineNumber = index + 1;

        // 检查数据有效性
        if (!currentItem[uniqueKey]) {
          failList.push({ line: lineNumber, name: '缺少唯一标识' });
          continue;
        }

        // 查询是否已存在（增加 additionalCondition 查询条件）
        const isExist = await entityName.findOne({
          where: {
            [uniqueKey]: currentItem[uniqueKey],
            ...additionalCondition, // 添加额外条件（如 class.id）
          },
        });

        if (isExist) {
          if (updateSupport) {
            try {
              // 更新现有记录
              await entityName.update(
                { [uniqueKey]: currentItem[uniqueKey], ...additionalCondition }, // 更新时也检查条件
                {
                  ...currentItem,
                  // updateBy: createBy,
                }
              );
              successList.push({ line: lineNumber, name: currentItem[uniqueKey] });
            } catch (error) {
              console.error('更新数据失败:', error.message);
              failList.push({ line: lineNumber, name: currentItem[uniqueKey] });
            }
          } else {
            failList.push({ line: lineNumber, name: currentItem[uniqueKey] });
          }
        } else {
          // 创建新记录
          await entityName.save({
            ...currentItem,
            createBy,
          });
          successList.push({ line: lineNumber, name: currentItem[uniqueKey] });
        }
      }
    } catch (error) {
      console.error('数据处理失败:', error.message);
      throw new Error('导入过程中发生错误');
    }

    return this.buildResultMessage(failList, successList);
  }

  private buildResultMessage(failList: any[], successList: any[]) {
    let errorTip = `导入失败的数据共计：<strong>${failList.length}</strong>条</br>`;
    let successTip = `导入成功的数据共计：<strong>${successList.length}</strong>条</br>`;

    failList.forEach(item => {
      errorTip += `第${item.line}行：数据项为 "${item.name}" 的数据已存在；</br>`;
    });

    successList.forEach(item => {
      successTip += `第${item.line}行：数据项为 "${item.name}" 的数据上传成功；</br>`;
    });

    return errorTip + successTip;
  }
}
